1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.base.Preconditions.checkNotNull;
20  
21  import com.google.common.collect.Synchronized.SynchronizedCollection;
22  import com.google.common.collect.Synchronized.SynchronizedSet;
23  import com.google.common.testing.SerializableTester;
24  
25  import junit.framework.TestCase;
26  
27  import java.io.Serializable;
28  import java.util.Collection;
29  import java.util.HashMap;
30  import java.util.Map;
31  import java.util.Set;
32  
33  /**
34   * Tests for {@code Synchronized#map}.
35   *
36   * @author Mike Bostock
37   */
38  public class SynchronizedMapTest extends TestCase {
39    public final Object mutex = new Integer(1); // something Serializable
40  
41    protected <K, V> Map<K, V> create() {
42      TestMap<K, V> inner = new TestMap<K, V>(new HashMap<K, V>(), mutex);
43      Map<K, V> outer = Synchronized.map(inner, mutex);
44      return outer;
45    }
46  
47    static class TestMap<K, V> extends ForwardingMap<K, V>
48        implements Serializable {
49      public final Object mutex;
50      private Map<K, V> delegate;
51      public TestMap(Map<K, V> delegate, Object mutex) {
52        checkNotNull(mutex);
53        this.delegate = delegate;
54        this.mutex = mutex;
55      }
56  
57      @Override protected Map<K, V> delegate() {
58        return delegate;
59      }
60  
61      @Override public int size() {
62        assertTrue(Thread.holdsLock(mutex));
63        return super.size();
64      }
65  
66      @Override public boolean isEmpty() {
67        assertTrue(Thread.holdsLock(mutex));
68        return super.isEmpty();
69      }
70  
71      @Override public V remove(Object object) {
72        assertTrue(Thread.holdsLock(mutex));
73        return super.remove(object);
74      }
75  
76      @Override public void clear() {
77        assertTrue(Thread.holdsLock(mutex));
78        super.clear();
79      }
80  
81      @Override public boolean containsKey(Object key) {
82        assertTrue(Thread.holdsLock(mutex));
83        return super.containsKey(key);
84      }
85  
86      @Override public boolean containsValue(Object value) {
87        assertTrue(Thread.holdsLock(mutex));
88        return super.containsValue(value);
89      }
90  
91      @Override public V get(Object key) {
92        assertTrue(Thread.holdsLock(mutex));
93        return super.get(key);
94      }
95  
96      @Override public V put(K key, V value) {
97        assertTrue(Thread.holdsLock(mutex));
98        return super.put(key, value);
99      }
100 
101     @Override public void putAll(Map<? extends K, ? extends V> map) {
102       assertTrue(Thread.holdsLock(mutex));
103       super.putAll(map);
104     }
105 
106     @Override public Set<K> keySet() {
107       assertTrue(Thread.holdsLock(mutex));
108       return super.keySet();
109     }
110 
111     @Override public Collection<V> values() {
112       assertTrue(Thread.holdsLock(mutex));
113       return super.values();
114     }
115 
116     @Override public Set<Entry<K, V>> entrySet() {
117       assertTrue(Thread.holdsLock(mutex));
118       return super.entrySet();
119     }
120 
121     @Override public boolean equals(Object obj) {
122       assertTrue(Thread.holdsLock(mutex));
123       return super.equals(obj);
124     }
125 
126     @Override public int hashCode() {
127       assertTrue(Thread.holdsLock(mutex));
128       return super.hashCode();
129     }
130 
131     @Override public String toString() {
132       assertTrue(Thread.holdsLock(mutex));
133       return super.toString();
134     }
135 
136     private static final long serialVersionUID = 0;
137   }
138 
139   /*
140    * This is somewhat of a weak test; we verify that all of the methods are
141    * correct, but not that they're actually forwarding correctly. We also rely
142    * on the other tests (e.g., SynchronizedSetTest) to verify that the
143    * collection views are synchronized correctly.
144    */
145 
146   public void testSize() {
147     create().size();
148   }
149 
150   public void testIsEmpty() {
151     create().isEmpty();
152   }
153 
154   public void testRemove() {
155     create().remove(null);
156   }
157 
158   public void testClear() {
159     create().clear();
160   }
161 
162   public void testContainsKey() {
163     create().containsKey(null);
164   }
165 
166   public void testContainsValue() {
167     create().containsValue(null);
168   }
169 
170   public void testGet() {
171     create().get(null);
172   }
173 
174   public void testPut() {
175     create().put(null, null);
176   }
177 
178   public void testPutAll() {
179     create().putAll(new HashMap<String, Integer>());
180   }
181 
182   public void testKeySet() {
183     Map<String, Integer> map = create();
184     Set<String> keySet = map.keySet();
185     assertTrue(keySet instanceof SynchronizedSet);
186     assertSame(mutex, ((SynchronizedSet<?>) keySet).mutex);
187   }
188 
189   public void testValues() {
190     Map<String, Integer> map = create();
191     Collection<Integer> values = map.values();
192     assertTrue(values instanceof SynchronizedCollection);
193     assertSame(mutex, ((SynchronizedCollection<?>) values).mutex);
194   }
195 
196   public void testEntrySet() {
197     Map<String, Integer> map = create();
198     Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
199     assertTrue(entrySet instanceof SynchronizedSet);
200     assertSame(mutex, ((SynchronizedSet<?>) entrySet).mutex);
201   }
202 
203   public void testEquals() {
204     create().equals(new HashMap<String, Integer>());
205   }
206 
207   public void testHashCode() {
208     create().hashCode();
209   }
210 
211   public void testToString() {
212     create().toString();
213   }
214 
215   public void testSerialization() {
216     SerializableTester.reserializeAndAssert(create());
217   }
218 }